home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc™ Source Code / UI / Disptch.cpp < prev    next >
Encoding:
Text File  |  1996-08-28  |  29.8 KB  |  1,090 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        Disptch.cpp
  3.  
  4.     Contains:    Implementation of class ODDispatcher
  5.  
  6.     Owned by:    Richard Rodseth
  7.  
  8.     Copyright:    © 1994 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <4>     6/14/96    CSL        1257735: Can't register for idle time
  13.                                     during idle time
  14.          <3>     6/12/96    eeh        1316602: set modifiers field for
  15.                                     manufactured events (e.g. mouseMoved)
  16.          <2>     5/01/96    NP        1300091,1282521: Replace badly written bug
  17.                                     workaround, IntlTSMEvent, with TSMEvent.
  18.         <50>    10/17/95    jpa        1292659: Ignore exceptions sending null
  19.                                     events to parts
  20.         <49>    10/10/95    DM        1277216: GM:API: Dont return ODPoint from
  21.                                     GetWindowPoint()
  22.         <48>     10/3/95    TJ        Changes done by RefBall Team
  23.         <47>      9/6/95    RR        #1282075 ADded ODVolatile
  24.         <46>     8/29/95    RR        # 1276401 Respect Mouse Focus
  25.         <45>     8/26/95    TÇ        1274606 FB2: Patching Remarks
  26.         <44>     8/23/95    NP        1264142: Don't Release null object.
  27.         <43>     8/15/95    RR        #1222870 Moved NULL handling to end of
  28.                                     method to allow patching/monitors
  29.         <42>      8/3/95    RR        #1257260: Collapse B classes. Remove
  30.                                     somInit methods. Don't call IsInitialized
  31.                                     or SubclassResponsibility
  32.         <41>     6/29/95    NP        1263893: Fix TSM support.
  33.         <40>     6/25/95    TÇ        1242642 BB: Turn on ODDebug warning if
  34.                                     refcount is wrong in
  35.                                     ODRefCntObjectsomUninit.
  36.         <39>     6/23/95    CC        1256943: MouseRegionIsInvalid: Replaced
  37.                                     StillDown with Button.
  38.         <38>     6/22/95    NP        1260250: Set up correctly for call to
  39.                                     CallEventHandler.
  40.         <37>     6/20/95    JP        1251250: ChangedReleaseExtension into
  41.                                     Release
  42.         <36>     6/15/95    RR        #1254828/1255536 Added Redispatch
  43.         <35>      6/8/95    RR        #1257260 Collapse base classes. #1214898
  44.                                     StdTypes.r -> ODTypes.r
  45.         <34>     5/31/95    RR        #1251403 Release after AcquirePart
  46.         <33>     5/26/95    RR        #1251403: Multithreading naming support
  47.         <32>     5/25/95    jpa        Fixed usage of ODDebug. [1253321]
  48.         <31>     5/21/95    NP        1251212: Wrap procs with UPPs.
  49.         <30>     5/17/95    RR        #1250135/1250137/1250143 Getters increment
  50.                                     refcount
  51.         <29>     5/10/95    RR        #1239139 MouseEnter etc.  over active
  52.                                                                         border go to container. Don't send
  53.                                     until mouse up.
  54.         <28>     5/10/95    RR         #1239139 MouseEnter etc.  over active
  55.                                     border go to container. Don't send until mouse up.
  56.         <27>     4/27/95    eeh        1230798: call part::ReleaseExtension
  57.         <26>      4/7/95    RR        #1216618 Added SOM_TRY etc.
  58.         <25>      4/4/95    RR        # 1211085 Removed fThreadsAvailable,
  59.                                     #1220104 Use ODObjectsAreEqual, #1228161
  60.                                     RegisterIdle does not update frequency if
  61.                                     called twice
  62.         <24>     3/20/95    jpa        Cooperative thread support [1167943]. Moved
  63.                                     bg click handler installation to private
  64.                                     impl file [1220704].
  65.         <23>     3/10/95    RR        # 1187137 Set Cursor to arrow in
  66.                                     InvalidateFacetUnderMouse
  67.         <22>     2/24/95    jpa        Install BG-mouse-down handler [1220704].
  68.                                     Use ODNewRgn. [1220810]
  69.         <21>     2/20/95    TÇ        #1221861 BB: Incomplete AOCE support needs
  70.                                     to be removed from OpenDoc
  71.         <20>     1/31/95    RR        # 1206909 Pass ev to
  72.                                     RemoveUnregisteredIdlers
  73.         <19>     1/25/95    jpa        Include StdExts.xh [1206907]
  74.         <18>     1/13/95    RR        Replace calls to MouseEnter etc with calls
  75.                                     to HandleEvent
  76.         <17>     1/12/95    jpa        Don't use obsolete Toolbox names [1211211].
  77.                                     Change qd --> ODQDGlobals [1210936]
  78.         <16>      1/9/95    NP        1194880: SemtIntf name changes.
  79.         <15>    11/28/94    RR        Prepare for thread support
  80.         <14>     9/30/94    RR        #1167950 Allow unregistering while idling.
  81.                                     Call RemoveUnregisteredIdlers in
  82.                                     HandleNULLEvent
  83.         <13>     9/29/94    RA        1189812: Mods for 68K build.
  84.         <12>     9/20/94    NP        1187682: Initial TSM support.
  85.         <11>     9/20/94    RR        #1154046 Moved ref counting into IdleList
  86.                                     methods so that an unregistered part is not
  87.                                     released. #1156594 Call
  88.                                     WindowState->HandleAOCEMailerEvent instead
  89.                                     of calling SMPMailerEvent directly.
  90.         <10>      9/2/94    eeh        #?: added SMPMailerEvent call to enable use
  91.                                     of mailer until Richard and I agree on a
  92.                                     cleaner fix to a bug in his hamper.
  93.          <9>     8/31/94    TÇ        #1183129, #1183116, #1183119, #1183111:
  94.                                     Lots of ErrorCode cleanup.
  95.          <8>     8/15/94    JBS        1181156: UI API Cleanup
  96.          <7>     8/10/94    JBS        1179919: coordinate system bias changes
  97.          <6>      8/4/94    eeh        bug 1177981: add
  98.                                     ODDispatcherGetDispatchModule
  99.          <5>     7/27/94    eeh        Changes necessitated by WinStat.idl changes
  100.          <4>     7/26/94    eeh        ODQDPoint->Point
  101.          <3>     6/30/94    CG        Moved InitStandardDispatchModule to
  102.                                     InitDispatch from InitSession.
  103.          <2>     9/27/94    RR        Call InitBaseDispatcher
  104.          <1>     9/26/94    RR        first checked in
  105.  
  106.     To Do:
  107.         * Get Gestalt bit for gestaltHasBGMouseDown.
  108.         * Call SetBgndMouseHandler via PrivateInterfaceLib if it's exported therefrom.
  109.         * Check whether bg mousedown handler calls are exported from PrivateInterfaceLib
  110.             and use those if they are (for Copland compatibility)
  111.         
  112.     In Progress:
  113.         
  114. */
  115.  
  116.  
  117. /*
  118.  *  This file was generated by the SOM Compiler.
  119.  *  Generated using: 
  120.  *      SOM Emitter emitxtm.dll: somc/smmain.c
  121.  */
  122.  
  123. #define ODDispatcher_Class_Source
  124. #define VARIABLE_MACROS
  125. #include <Disptch.xih>
  126.  
  127. #ifndef SOM_ODDispatchModule_xh
  128. #include "DispMod.xh"
  129. #endif
  130.  
  131. #ifndef SOM_ODWindowState_xh
  132. #include "WinStat.xh"
  133. #endif
  134.  
  135. #ifndef SOM_ODWindow_xh
  136. #include "Window.xh"
  137. #endif
  138.  
  139. #ifndef SOM_ODSession_xh
  140. #include "ODSessn.xh"
  141. #endif
  142.  
  143. #ifndef _TEMPOBJ_
  144. #include <TempObj.h>
  145. #endif
  146.  
  147. #ifndef _IDLELIST_
  148. #include "IdleList.h"
  149. #endif
  150.  
  151. #ifndef _ORDCOLL_
  152. #include "OrdColl.h"
  153. #endif
  154.  
  155. #ifndef _DISPTABL_
  156. #include "DispTabl.h"
  157. #endif
  158.  
  159. #ifndef SOM_ODFacet_xh
  160. #include "Facet.xh"
  161. #endif
  162.  
  163. #ifndef SOM_ODFrame_xh
  164. #include "Frame.xh"
  165. #endif
  166.  
  167. #ifndef SOM_ODPart_xh
  168. #include "Part.xh"
  169. #endif
  170.  
  171. #ifndef _EXCEPT_
  172. #include "Except.h"
  173. #endif
  174.  
  175. #ifndef SOM_ODStandardDispatchModule_xh
  176. #include <StdDisp.xh>
  177. #endif
  178.  
  179. #ifndef _ODDEBUG_
  180. #include "ODDebug.h"
  181. #endif
  182.  
  183. #ifndef SOM_ODArbitrator_xh
  184. #include <Arbitrat.xh>
  185. #endif
  186.  
  187. #ifndef SOM_ODSemanticInterface_xh
  188. #include <SemtIntB.xh>
  189. #endif
  190.  
  191. #ifndef SOM_ODAppleEvent_xh
  192. #include <ODAplEvt.xh>
  193. #endif
  194.  
  195. #ifndef _BARRAY_
  196. #include "BArray.h"
  197. #endif
  198.  
  199. #ifndef _ODDESUTL_
  200. #include "ODDesUtl.h"
  201. #endif
  202.  
  203. #ifndef SOM_Module_OpenDoc_Foci_defined
  204. #include <Foci.xh>
  205. #endif
  206.  
  207. #ifndef SOM_Module_OpenDoc_StandardExtensions_defined
  208. #include <StdExts.xh>
  209. #endif
  210.  
  211. #ifndef _DSPUTILM_
  212. #include "DspUtilM.h"
  213. #endif
  214.  
  215. #ifndef _BGCLICKM_
  216. #include "BGClickM.h"
  217. #endif
  218.  
  219. #ifndef _ODTHREDM_
  220. #include "ODThredM.h"
  221. #endif
  222.  
  223. #ifndef __TEXTSERVICES_
  224. #include "TextServices.h"
  225. #endif
  226.  
  227. #ifndef __GESTALTEQU__
  228. #include <GestaltEqu.h>
  229. #endif
  230.  
  231. #define ODLogEvents 0
  232.  
  233. //------------------------------------------------------------------------------
  234. //    ODDispatcher
  235. //------------------------------------------------------------------------------
  236.  
  237. #pragma segment ODDispatcher
  238.  
  239. #include "DisptchB.cpp"    // Platform-independent methods, if any
  240.  
  241. SOM_Scope void  SOMLINK ODDispatcherRegisterIdle(ODDispatcher *somSelf, Environment *ev,
  242.         ODPart* part,
  243.         ODFrame* frame,
  244.         ODIdleFrequency frequency)
  245. {
  246.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  247.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherRegisterIdle");
  248.  
  249.     SOM_TRY
  250.     
  251.         if (part)
  252.             _fIdleList->AddIdle(ev, part, frame, frequency);
  253.  
  254.     SOM_CATCH_ALL
  255.     SOM_ENDTRY
  256. }
  257.  
  258. SOM_Scope void  SOMLINK ODDispatcherUnregisterIdle(ODDispatcher *somSelf, Environment *ev,
  259.         ODPart* part,
  260.         ODFrame* frame)
  261. {
  262.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  263.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherUnregisterIdle");
  264.  
  265.     SOM_TRY
  266.  
  267.         if (part)
  268.             _fIdleList->RemoveIdle(ev, part, frame);
  269.  
  270.     SOM_CATCH_ALL
  271.     SOM_ENDTRY
  272. }
  273.  
  274. SOM_Scope void  SOMLINK ODDispatcherSetIdleFrequency(ODDispatcher *somSelf, Environment *ev,
  275.         ODPart* part,
  276.         ODFrame* frame,
  277.         ODIdleFrequency frequency)
  278. {
  279.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  280.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherSetIdleFrequency");
  281.  
  282.     SOM_TRY
  283.  
  284.         if (part)
  285.             _fIdleList->SetIdleFrequency(ev, part, frame, frequency);
  286.  
  287.     SOM_CATCH_ALL
  288.     SOM_ENDTRY
  289. }
  290.  
  291. SOM_Scope void  SOMLINK ODDispatcherYield(ODDispatcher *somSelf, Environment *ev,
  292.         ODFrame* frame)
  293. {
  294.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  295.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherYield");
  296.  
  297.     SOM_TRY
  298.  
  299.     /*
  300.         Will Call WaitNextEvent(), masking out all but null and update events.
  301.         Idle events are sent to all but the part that yielded
  302.     */
  303.         const    ODSLong        kODSleepTicks             =     20L;//    Number sleep ticks
  304.     
  305.         EventRecord        eventRec;    
  306.         WaitNextEvent ( updateMask, &eventRec, somSelf->GetSleepTime(ev), somSelf->GetMouseRegion(ev) ) ;
  307.         if (eventRec.what == nullEvent)
  308.             somSelf->HandleNullEvent(ev, (ODEventData*) &eventRec, frame);    // Note Cast
  309.         else
  310.             somSelf->Dispatch(ev, (ODEventData*) &eventRec);
  311.     
  312.  
  313.     SOM_CATCH_ALL
  314.     SOM_ENDTRY
  315. }
  316.  
  317. SOM_Scope void  SOMLINK ODDispatcherSetMouseRegion(ODDispatcher *somSelf, Environment *ev,
  318.         ODRgnHandle area)
  319. {
  320.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  321.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherSetMouseRegion");
  322.  
  323.     if (area && _fPartMouseRegion)
  324.     {
  325.         CopyRgn(area, _fPartMouseRegion);
  326.     }
  327.  
  328. }
  329.  
  330. SOM_Scope ODRgnHandle  SOMLINK ODDispatcherGetMouseRegion(ODDispatcher *somSelf, Environment *ev)
  331. {
  332.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  333.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherGetMouseRegion");
  334.  
  335.     SOM_TRY
  336.  
  337.         if (somSelf->MouseRegionIsInvalid(ev))
  338.             somSelf->ComputeMouseRegion(ev);
  339.     
  340.     
  341.     /*
  342.     
  343.             CGrafPort desktopPort;                    // Used for showing cursor region 
  344.             long ticks;                                // Used for showing cursor region 
  345.             GrafPtr savedPort;                        // Used for showing cursor region 
  346.     
  347.             // Cursor region is in global coords. Need to create desktop port 
  348.             GetPort(&savedPort);
  349.             OpenCPort(&desktopPort);
  350.             CopyRgn(GetGrayRgn(), desktopPort.visRgn);
  351.             desktopPort.portRect = (*(desktopPort.visRgn))->rgnBBox;
  352.     
  353.             PenNormal();
  354.             PenMode(patXor);
  355.     
  356.             PaintRgn(_fPartMouseRegion);
  357.             Delay(30, &ticks);
  358.             PaintRgn(_fMouseRegion);
  359.     
  360.             CloseCPort(&desktopPort);
  361.             SetPort(savedPort);
  362.     
  363.     
  364.     */
  365.  
  366.     return _fMouseRegion;
  367.  
  368.     SOM_CATCH_ALL
  369.         
  370.         return kODNULL;
  371.         
  372.     SOM_ENDTRY
  373.     
  374.     return kODNULL;
  375. }
  376.  
  377. SOM_Scope void  SOMLINK ODDispatcherInvalidateFacetUnderMouse(ODDispatcher *somSelf, Environment *ev)
  378. {
  379.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  380.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherInvalidateFacetUnderMouse");
  381.  
  382.     SOM_TRY
  383.     
  384.         _fFacetUnderMouse = kODNULL;
  385.         somSelf->InvalidateMouseRegion(ev);
  386.         SetCursor(&ODQDGlobals.arrow);
  387.  
  388.     SOM_CATCH_ALL
  389.     SOM_ENDTRY
  390. }
  391.  
  392. SOM_Scope ODSLong  SOMLINK ODDispatcherGetSleepTime(ODDispatcher *somSelf, Environment *ev)
  393. {
  394.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  395.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherGetSleepTime");
  396.  
  397.     SOM_TRY
  398.     
  399.         // Don't sleep at all if another thread is ready to run:
  400.         if( ODAnyThreadsReady() )
  401.             return 0;
  402.     
  403.         return _fIdleList->GetMinIdleFrequency();
  404.  
  405.     SOM_CATCH_ALL
  406.         
  407.         return 0;
  408.     
  409.     SOM_ENDTRY
  410.     
  411.     return 0;
  412. }
  413.  
  414. static OSErr pascal HandleTSMEvents(const AppleEvent *theAppleEvent,
  415.                                         AppleEvent *reply,
  416.                                         long handlerRefcon)
  417. {
  418.     ODSession*        session = (ODSession*)handlerRefcon;
  419.     Environment*    ev = somGetGlobalEnvironment();
  420. //    DescType        eventID;
  421. //    DescType        actualType;
  422.     Size            maxSize = sizeof(DescType);
  423. //    Size            actualSize;
  424.     OSErr            result = noErr;
  425.     ODSemanticInterface* semtIntf = kODNULL; ODVolatile(semtIntf);
  426.     ODPart* keyPart = kODNULL; ODVolatile(keyPart);
  427.  
  428.     TRY
  429.         TempODFrame keyFrame
  430.             = session->GetArbitrator(ev)->AcquireFocusOwner(ev,
  431.                                                 session->Tokenize(ev,
  432.                                                                     kODKeyFocus));
  433.             // -- TÇ tempobj'd
  434.         if ((ODFrame*)keyFrame != kODNULL)
  435.         {
  436.             keyPart = keyFrame->AcquirePart(ev);
  437.             if (keyPart->HasExtension(ev, kODExtSemanticInterface))
  438.             {
  439.                 semtIntf = (ODSemanticInterface*)keyPart->AcquireExtension(ev,
  440.                                                         kODExtSemanticInterface);
  441.                 // WHAT WAS I GOING TO DO WITH THIS INFO? - NP 6/21/95
  442. //                result = AEGetAttributePtr(theAppleEvent, keyEventIDAttr,
  443. //                                                    typeType, &actualType,
  444. //                                                    (Ptr)&eventID, maxSize,
  445. //                                                    &actualSize);
  446. //                if (result || actualType != typeType || actualSize != maxSize)
  447. //                    THROW(errAEEventNotHandled);
  448.  
  449.                 // CREATE NEW ODAPPLEEVENTS FOR THE PARAMETERS
  450.                 ODAppleEvent*    odEvent = new ODAppleEvent;
  451.                 THROW_IF_NULL(odEvent);
  452.                 odEvent->InitODAppleEvent(ev);
  453.                 AEDescToODDesc((AEDesc*)theAppleEvent, odEvent);
  454.                 ODAppleEvent*    odReply = new ODAppleEvent;
  455.                 THROW_IF_NULL(odReply);
  456.                 odReply->InitODAppleEvent(ev);
  457.                 AEDescToODDesc((AEDesc*)reply, odReply);
  458.                 
  459.                 // PASS THE EVENT TO THE PART
  460.                 TRY
  461.                     semtIntf->CallEventHandler(ev, keyPart, odEvent, odReply);
  462.                 CATCH_ALL
  463.                     result = ErrorCode();
  464.                 ENDTRY
  465.                 
  466.                 // CLEAN UP. NOTE, WE MUST UPDATE THE REPLY DATAHANDLE SO THAT
  467.                 //    THE APPLE EVENTS MANAGER SEES THE CHANGE (IF ANY).
  468.                 delete odEvent;
  469.                 if (reply->descriptorType != typeNull
  470.                         && reply->dataHandle != kODNULL
  471.                         && !result)
  472.                 {
  473.                     ODByteArray data = odReply->GetRawData(ev);
  474.                     SetHandleSize(reply->dataHandle, data._length);
  475.                     THROW_IF_ERROR(MemError());
  476.                     ODBlockMove(data._buffer, *(reply->dataHandle),
  477.                                     data._length);
  478.                     DisposeByteArrayStruct(data);
  479.                 }
  480.                 delete odReply;
  481.             }
  482.             else
  483.                 result = errAEEventNotHandled;
  484.         }
  485.         else
  486.             result = errAEEventNotHandled;
  487.     CATCH_ALL
  488.         result = ErrorCode();
  489.     ENDTRY
  490.     
  491.     if ( semtIntf != kODNULL )
  492.         semtIntf->Release(ev);
  493.     if ( keyPart != kODNULL )
  494.         keyPart->Release(ev);
  495.  
  496.     return result;
  497. }
  498.  
  499. SOM_Scope void  SOMLINK ODDispatcherInitDispatcher(ODDispatcher *somSelf, Environment *ev,
  500.         ODSession* session)
  501. {
  502.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  503.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherInitDispatcher");
  504.     
  505.     const Boolean    kIsSysHandler = kODTrue;
  506.  
  507.     SOM_TRY
  508.  
  509.         /* Moved from somInit. SOM itself sets fields to zero
  510.         _fExit = kODFalse;
  511.         _fDispatchTable = kODNULL;
  512.         _fSession = kODNULL;
  513.         _fIdleList = kODNULL;
  514.     
  515.         _fMouseRegion = kODNULL;
  516.         _fPartMouseRegion = kODNULL;
  517.         _fFacetUnderMouse = kODNULL;
  518.         */
  519.         
  520.         somSelf->InitObject(ev);
  521.     
  522.         _fSession = session;
  523.     
  524.         _fDispatchTable = new DispatchTable;
  525.         THROW_IF_NULL(_fDispatchTable);
  526.         
  527.         _fIdleList = new IdleList;
  528.         THROW_IF_NULL(_fIdleList);
  529.         
  530.         _fMouseRegion = ODNewRgn();
  531.             
  532.         _fPartMouseRegion = ODNewRgn();
  533.     
  534.         ODStandardDispatchModule* stdModule = kODNULL;
  535.     
  536.         stdModule =    new ODStandardDispatchModule();
  537.         THROW_IF_NULL(stdModule);
  538.         stdModule->InitStandardDispatchModule(ev,session);
  539.         
  540.         somSelf->AddDispatchModule(ev,mouseDown,  stdModule);
  541.  
  542.         somSelf->AddDispatchModule(ev,mouseUp,    stdModule);
  543.         somSelf->AddDispatchModule(ev,keyDown,    stdModule);
  544.         somSelf->AddDispatchModule(ev,keyUp,      stdModule);
  545.         somSelf->AddDispatchModule(ev,autoKey,    stdModule);
  546.         somSelf->AddDispatchModule(ev,updateEvt,  stdModule);
  547.         somSelf->AddDispatchModule(ev,diskEvt,    stdModule);
  548.         somSelf->AddDispatchModule(ev,activateEvt,stdModule);
  549.         somSelf->AddDispatchModule(ev,osEvt,      stdModule);
  550.         somSelf->AddDispatchModule(ev,kHighLevelEvent, stdModule);
  551.         somSelf->AddDispatchModule(ev,kODEvtMenu, stdModule);
  552.         somSelf->AddDispatchModule(ev,kODEvtBGMouseDown, stdModule);
  553.         somSelf->AddDispatchModule(ev,kODEvtMouseDownBorder, stdModule);
  554.         somSelf->AddDispatchModule(ev,kODEvtMouseDownEmbedded, stdModule);
  555.         somSelf->AddDispatchModule(ev,kODEvtBGMouseDownEmbedded, stdModule);
  556.         somSelf->AddDispatchModule(ev,kODEvtMouseUpEmbedded, stdModule);
  557.     
  558.         // TSM support
  559.         AEEventHandlerUPP proc = NewAEEventHandlerProc(HandleTSMEvents);
  560.         THROW_IF_ERROR(AEInstallEventHandler(kTextServiceClass,
  561.                                                 kUpdateActiveInputArea,
  562.                                                 proc,
  563.                                                 (long)_fSession,
  564.                                                 !kIsSysHandler));
  565.         THROW_IF_ERROR(AEInstallEventHandler(kTextServiceClass, kPos2Offset,
  566.                                                 proc,
  567.                                                 (long)_fSession,
  568.                                                 !kIsSysHandler));
  569.         THROW_IF_ERROR(AEInstallEventHandler(kTextServiceClass, kOffset2Pos,
  570.                                                 proc,
  571.                                                 (long)_fSession,
  572.                                                 !kIsSysHandler));
  573.         THROW_IF_ERROR(AEInstallEventHandler(kTextServiceClass,
  574.                                                 kShowHideInputWindow,
  575.                                                 proc,
  576.                                                 (long)_fSession,
  577.                                                 !kIsSysHandler));
  578.     
  579.         // Background mouse-down support:
  580.         ODInstallBGMouseDownHandler(session);
  581.         
  582.         // Thread support:
  583.         ODInitThreads();
  584.  
  585.     SOM_CATCH_ALL
  586.     SOM_ENDTRY
  587. }
  588.  
  589. SOM_Scope void  SOMLINK ODDispatcherInvalidateMouseRegion(ODDispatcher *somSelf, Environment *ev)
  590. {
  591.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  592.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherInvalidateMouseRegion");
  593.  
  594.     SOM_TRY
  595.  
  596.         ASSERT(_fPartMouseRegion != kODNULL, kODErrDispatcherNotInitialized);
  597.         SetEmptyRgn(_fPartMouseRegion);
  598.  
  599.     SOM_CATCH_ALL
  600.     SOM_ENDTRY
  601. }
  602.  
  603. SOM_Scope ODFacet*  SOMLINK ODDispatcherGetFacetUnderMouse(ODDispatcher *somSelf, Environment *ev)
  604. {
  605.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  606.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherGetFacetUnderMouse");
  607.  
  608.     return _fFacetUnderMouse;
  609. }
  610.  
  611. SOM_Scope void  SOMLINK ODDispatcherSetFacetUnderMouse(ODDispatcher *somSelf, Environment *ev,
  612.         ODFacet* facet)
  613. {
  614.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  615.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherSetFacetUnderMouse");
  616.  
  617.  
  618.     _fFacetUnderMouse = facet;
  619.  
  620. }
  621.  
  622. SOM_Scope ODBoolean  SOMLINK ODDispatcherHandleNullEvent(ODDispatcher *somSelf, Environment *ev,
  623.         ODEventData* event,
  624.         ODFrame* skipFrame)
  625. {
  626.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  627.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherHandleNullEvent");
  628.  
  629.     ODBoolean handled = kODFalse;
  630.     
  631.     SOM_TRY
  632.     
  633.         // Give threads time to run:
  634.         ODYield();
  635.     
  636.         IdleListIterator iter(_fIdleList);
  637.         ODFrame* frame = kODNULL;
  638.         ODTicks now = TickCount();
  639.         
  640.         for (IdleInfo* idleInfo = iter.First(); iter.IsNotComplete(); idleInfo = iter.Next())
  641.         {
  642.             if ( (idleInfo->NeedsIdle( now )))
  643.             {
  644.                 frame = idleInfo->GetFrame(); 
  645.                 if ( (frame == kODNULL) || !ODObjectsAreEqual(ev, frame,skipFrame) ) 
  646.                 {
  647.                     TRY{
  648.                         idleInfo->GetPart()->HandleEvent(ev,event, frame, kODNULL, kODNULL);
  649.                     }CATCH_ALL{
  650.                         // ignore exception
  651.                     }ENDTRY
  652.                     idleInfo->SetLastIdle( now );
  653.                 }
  654.             }
  655.         }
  656.         handled = kODTrue;
  657.  
  658.     SOM_CATCH_ALL
  659.     SOM_ENDTRY
  660.     
  661.     return handled;
  662. }
  663.  
  664. SOM_Scope ODBoolean  SOMLINK ODDispatcherMouseRegionIsInvalid(ODDispatcher *somSelf, Environment *ev)
  665. {
  666.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  667.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherMouseRegionIsInvalid");
  668.  
  669.     ODBoolean isInvalid = kODTrue;
  670.  
  671.     if (Button())
  672.         return kODFalse;
  673.     
  674.     SOM_TRY
  675.  
  676.         ASSERT(_fPartMouseRegion != kODNULL, kODErrDispatcherNotInitialized);
  677.         isInvalid = EmptyRgn(_fPartMouseRegion);
  678.  
  679.     SOM_CATCH_ALL
  680.     SOM_ENDTRY
  681.     
  682.     return isInvalid;
  683. }
  684.  
  685. SOM_Scope void  SOMLINK ODDispatcherComputeMouseRegion(ODDispatcher *somSelf, Environment *ev)
  686. {
  687.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  688.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherComputeMouseRegion");
  689.  
  690.     SOM_TRY
  691.  
  692.         somSelf->CheckFacetUnderMouse(ev); // A Part may call SetMouseRegion
  693.         /*
  694.             if no frame is under the mouse, compute an appropriate big region
  695.             either way, add the current mouse location? 
  696.             And clip region to frame shape?
  697.         */
  698.     
  699.         // Add the current mouse location to whatever region is computed by the part
  700.         Point globalMouse;
  701.         GetMouse(&globalMouse);
  702.         LocalToGlobal(&globalMouse);
  703.         
  704.         SetRectRgn(_fMouseRegion, globalMouse.h, globalMouse.v, globalMouse.h + 1, globalMouse.v + 1);
  705.         UnionRgn(_fPartMouseRegion, _fMouseRegion, _fPartMouseRegion);
  706.  
  707.     SOM_CATCH_ALL
  708.     SOM_ENDTRY
  709. }
  710.  
  711. // <eeh> note: this code is a slightly modified version of IsThisKeyDown found
  712. // in ODDebug.cpp.  I'm using this instead because 1) I'm not sure it's available
  713. // when ODDebug isn't defined; and 2) because this calls GetKeys only once instead
  714. // of four times as would be necessary were IsThisKeyDown to be used.
  715.  
  716. inline Boolean OneDown( unsigned char keyMap[], ODUShort key )
  717.     { return ((keyMap[key >> 3] >> (key & 7)) & 1); }
  718.  
  719. ODBoolean IsThisKeyDown(ODUShort theKey);
  720. static ODSShort Modifiers()
  721. {
  722.     unsigned char theKeys[16];
  723.     GetKeys((UInt32*)&theKeys);
  724.  
  725.     ODSShort mods = 0;
  726.     // the index into the key map is the virtual keycode - 1....
  727.     if (OneDown(theKeys, 0x0038))
  728.         mods |= shiftKey;
  729.     if (OneDown(theKeys, 0x003A))
  730.         mods |= optionKey;
  731.     if (OneDown(theKeys, 0x003B))
  732.         mods |= controlKey;
  733.     if (OneDown(theKeys, 0x0037))
  734.         mods |= cmdKey;
  735.     return mods;
  736. }
  737.  
  738. SOM_Scope void  SOMLINK ODDispatcherCheckFacetUnderMouse(ODDispatcher *somSelf, Environment *ev)
  739. {
  740.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  741.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherCheckFacetUnderMouse");
  742.  
  743.     SOM_TRY
  744.  
  745.         Point globalPoint;
  746.         ODPoint windowPoint;
  747.     
  748.         GetMouse(&globalPoint);
  749.         LocalToGlobal(&globalPoint);
  750.     
  751.         if (!SetTSMCursor(globalPoint)) // NP: temporary. dispatcher really needs
  752.                                         //    to set a 1-pixel mouse region so that
  753.                                         //    SetTSMCursor can be called every time
  754.                                         //    the mouse moves.
  755.         {
  756.             ODWindow* odWindow = kODNULL;
  757.             ODFacet* foundFacet = kODNULL;
  758.         
  759.             ODWindowState* _fWindowState = _fSession->GetWindowState(ev); // temp
  760.             
  761.             TempODFrame mouseFocusFrame = kODNULL;
  762.             mouseFocusFrame = _fSession->GetArbitrator(ev)->AcquireFocusOwner(ev, _fSession->Tokenize(ev,kODMouseFocus));
  763.  
  764.             if (mouseFocusFrame)
  765.             {
  766.  
  767.                     if (_fFacetUnderMouse && ODObjectsAreEqual(ev, mouseFocusFrame, _fFacetUnderMouse->GetFrame(ev)))
  768.                     {
  769.                         odWindow = _fFacetUnderMouse->GetWindow(ev);
  770.                         odWindow->GetWindowPoint(ev, &globalPoint, &windowPoint);
  771.                         
  772.                         ODEventData event;
  773.                         SetEvent(event,kODEvtMouseWithin, globalPoint, Modifiers() );
  774.                         ODEventInfo info;
  775.                         SetEventInfo(info, windowPoint);
  776.                         WindowToLocal(ev, info.where, _fFacetUnderMouse);
  777.                     
  778.                         TempODPart part = mouseFocusFrame->AcquirePart(ev);
  779. #if ODDebug && ODLogEvents
  780.     LogEvent(&event, &info, mouseFocusFrame, _fFacetUnderMouse);
  781. #endif
  782.                         part->HandleEvent(ev, &event, mouseFocusFrame, _fFacetUnderMouse, &info);
  783.                     }
  784.                     return;
  785.             }
  786.  
  787.             odWindow = _fWindowState->FindODWindow(ev, &globalPoint);
  788.                 
  789.             if (odWindow)
  790.             {
  791.                 TempODWindow tempWindow = odWindow; // ensure it's released
  792.                 odWindow->GetWindowPoint(ev, &globalPoint, &windowPoint);
  793.                 TempODFrame activeFrame = _fSession->GetArbitrator(ev)->AcquireFocusOwner(ev, _fSession->Tokenize(ev,kODSelectionFocus));
  794.                 ODFacet* activeFacet = activeFrame ? GetActiveFacetWithBorderUnderPoint(ev, activeFrame, odWindow, windowPoint) : kODNULL;
  795.                 
  796.                 if (activeFacet)
  797.                     foundFacet = activeFacet->GetContainingFacet(ev);
  798.                 else
  799.                 {
  800.                     foundFacet = odWindow->GetFacetUnderPoint(ev, &windowPoint);
  801.                     if (foundFacet && (foundFacet->GetFrame(ev)->IsFrozen(ev) || foundFacet->IsSelected(ev)))
  802.                         foundFacet = foundFacet->GetContainingFacet(ev);
  803.                 }
  804.             }
  805.         
  806.             
  807.             if (ODObjectsAreEqual(ev, foundFacet, _fFacetUnderMouse))    
  808.             {
  809.                 if (foundFacet)
  810.                 {
  811.                     ODEventData event;
  812.                     SetEvent(event,kODEvtMouseWithin, globalPoint, Modifiers());
  813.                     ODEventInfo info;
  814.                     SetEventInfo(info, windowPoint);
  815.                     WindowToLocal(ev, info.where, _fFacetUnderMouse);
  816.                     
  817.                     ODFrame* frame = _fFacetUnderMouse->GetFrame(ev);
  818. #if ODDebug && ODLogEvents
  819.     LogEvent(&event, &info, frame, _fFacetUnderMouse);
  820. #endif
  821.                     TempODPart part = frame->AcquirePart(ev);
  822.                     part->HandleEvent(ev, &event, frame, _fFacetUnderMouse, &info);
  823.                 }
  824.             }
  825.             else
  826.             {        
  827.                 if (_fFacetUnderMouse)
  828.                 {
  829.                     ODEventData event;
  830.                     SetEvent(event,kODEvtMouseLeave, globalPoint, Modifiers());
  831.                     ODEventInfo info;
  832.                     SetEventInfo(info, windowPoint);
  833.                     WindowToLocal(ev, info.where, _fFacetUnderMouse);
  834.                     
  835.                     ODFrame* frame = _fFacetUnderMouse->GetFrame(ev);
  836. #if ODDebug && ODLogEvents
  837.     LogEvent(&event, &info, frame, _fFacetUnderMouse);
  838. #endif
  839.                     TempODPart part = frame->AcquirePart(ev);
  840.                     part->HandleEvent(ev, &event, frame, _fFacetUnderMouse, &info);
  841.                 }
  842.                 if (foundFacet)
  843.                 { 
  844.                     ODEventData event;
  845.                     SetEvent(event,kODEvtMouseEnter, globalPoint, Modifiers());
  846.                     ODEventInfo info;
  847.                     SetEventInfo(info, windowPoint);
  848.                     WindowToLocal(ev, info.where, foundFacet);
  849.                     
  850.                     ODFrame* frame = foundFacet->GetFrame(ev);
  851. #if ODDebug && ODLogEvents
  852.     LogEvent(&event, &info, frame, foundFacet);
  853. #endif
  854.                     TempODPart part = frame->AcquirePart(ev);
  855.                     part->HandleEvent(ev, &event,frame,foundFacet, &info);
  856.                 }
  857.                 _fFacetUnderMouse = foundFacet;
  858.             }
  859.         }
  860.  
  861.     SOM_CATCH_ALL
  862.     SOM_ENDTRY
  863. }
  864.  
  865. SOM_Scope void  SOMLINK ODDispatchersomUninit(ODDispatcher *somSelf)
  866. {
  867.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  868.     ODDispatcherMethodDebug("ODDispatcher","ODDispatchersomUninit");
  869.  
  870.      ODDeleteObject(_fDispatchTable);
  871.     ODDeleteObject(_fIdleList);
  872.     ODDisposeHandle((Handle)_fMouseRegion);
  873.     ODDisposeHandle((Handle)_fPartMouseRegion);
  874.    
  875.        parent_somUninit(somSelf);
  876. }
  877.  
  878. SOM_Scope ODSize  SOMLINK ODDispatcherPurge(ODDispatcher *somSelf, Environment *ev,
  879.         ODSize size)
  880. {
  881.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  882.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherPurge");
  883.  
  884.     ODUnused(size);
  885.     return 0;
  886. }
  887.  
  888. SOM_Scope void  SOMLINK ODDispatcherAddDispatchModule(ODDispatcher *somSelf, Environment *ev,
  889.         ODEventType eventType,
  890.         ODDispatchModule* dispatchModule)
  891. {
  892.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  893.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherAddDispatchModule");
  894.  
  895.     SOM_TRY
  896.  
  897.         ASSERT(_fDispatchTable != kODNULL,kODErrDispatcherNotInitialized);
  898.         
  899.         if (dispatchModule)
  900.         {
  901.             _fDispatchTable->AddDispatchModule(eventType,dispatchModule);
  902.         }
  903.         else
  904.             THROW(kODErrIllegalNullDispatchModuleInput);
  905.     
  906.  
  907.     SOM_CATCH_ALL
  908.     SOM_ENDTRY
  909. }
  910.  
  911. SOM_Scope ODDispatchModule*  SOMLINK ODDispatcherGetDispatchModule(ODDispatcher *somSelf, Environment *ev,
  912.         ODEventType eventType)
  913. {
  914.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  915.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherGetDispatchModule");
  916.     
  917.     ODDispatchModule* module = kODNULL;
  918.  
  919.     SOM_TRY
  920.  
  921.         ASSERT(_fDispatchTable != kODNULL,kODErrDispatcherNotInitialized);
  922.     
  923.         module = _fDispatchTable->GetDispatchModule( eventType );
  924.  
  925.     SOM_CATCH_ALL
  926.     SOM_ENDTRY
  927.     
  928.     return module;
  929. }
  930.  
  931. SOM_Scope void  SOMLINK ODDispatcherRemoveDispatchModule(ODDispatcher *somSelf, Environment *ev,
  932.         ODEventType eventType)
  933. {
  934.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  935.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherRemoveDispatchModule");
  936.  
  937.     SOM_TRY
  938.  
  939.         ASSERT(_fDispatchTable != kODNULL,kODErrDispatcherNotInitialized);
  940.         
  941.         _fDispatchTable->RemoveDispatchModule(eventType);
  942.  
  943.     SOM_CATCH_ALL
  944.     SOM_ENDTRY
  945. }
  946.  
  947. SOM_Scope void  SOMLINK ODDispatcherAddMonitor(ODDispatcher *somSelf, Environment *ev,
  948.         ODEventType eventType,
  949.         ODDispatchModule* dispatchModule)
  950. {
  951.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  952.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherAddMonitor");
  953.  
  954.     SOM_TRY
  955.  
  956.         ASSERT(_fDispatchTable != kODNULL,kODErrDispatcherNotInitialized);
  957.         
  958.         if (dispatchModule)
  959.             _fDispatchTable->AddMonitor(eventType,dispatchModule);        
  960.         else
  961.             THROW(kODErrIllegalNullDispatchModuleInput);
  962.  
  963.     SOM_CATCH_ALL
  964.     SOM_ENDTRY
  965. }
  966.  
  967. SOM_Scope void  SOMLINK ODDispatcherRemoveMonitor(ODDispatcher *somSelf, Environment *ev,
  968.         ODEventType eventType,
  969.         ODDispatchModule* dispatchModule)
  970. {
  971.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  972.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherRemoveMonitor");
  973.  
  974.     SOM_TRY
  975.  
  976.         ASSERT(_fDispatchTable != kODNULL,kODErrDispatcherNotInitialized);
  977.         
  978.         _fDispatchTable->RemoveMonitor(eventType, dispatchModule);
  979.  
  980.     SOM_CATCH_ALL
  981.     SOM_ENDTRY
  982. }
  983.  
  984.  
  985. static Boolean IntlTSMEvent(EventRecord *event) // NP: from TE 27.
  986. {
  987.     short oldFont;
  988.     ScriptCode keyboardScript;
  989.     
  990.     // make sure we have a port and it's not the Window Manager port
  991.     if (ODQDGlobals.thePort != nil && FrontWindow() != nil)
  992.     {
  993.         oldFont = ODQDGlobals.thePort->txFont;
  994.         keyboardScript = GetScriptManagerVariable(smKeyScript);
  995.         if (FontToScript(oldFont) != keyboardScript)
  996.             TextFont(GetScriptVariable(keyboardScript, smScriptAppFond));
  997.     };
  998.     return TSMEvent(event);
  999. }
  1000.  
  1001. SOM_Scope ODBoolean  SOMLINK ODDispatcherDispatch(ODDispatcher *somSelf, Environment *ev,
  1002.         ODEventData* eventData)
  1003. {
  1004.     ODBoolean handled = kODFalse;
  1005.     
  1006.     SOM_TRY
  1007.  
  1008.         ODEventInfo eventInfo;    // Note: Need some utility functions
  1009.         eventInfo.embeddedFrame = kODNULL;
  1010.         eventInfo.embeddedFacet = kODNULL;
  1011.         ODPoint zero(0,0);
  1012.         eventInfo.where = zero;
  1013.         eventInfo.propagated = kODFalse;
  1014.     
  1015.         handled =somSelf->Redispatch(ev, eventData, &eventInfo);
  1016.     
  1017.     SOM_CATCH_ALL
  1018.     SOM_ENDTRY
  1019.     
  1020.     return handled;
  1021. }
  1022.  
  1023. SOM_Scope ODBoolean  SOMLINK ODDispatcherRedispatch(ODDispatcher *somSelf, Environment *ev,
  1024.         ODEventData* eventData,
  1025.         ODEventInfo* eventInfo)
  1026. {
  1027.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  1028.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherDispatch");
  1029.  
  1030.     ODBoolean handled = kODFalse;
  1031.     ODEventType eventType = eventData->what;     
  1032.  
  1033.     SOM_TRY
  1034.  
  1035.         ASSERT(_fDispatchTable != kODNULL,kODErrDispatcherNotInitialized);
  1036.         
  1037.         {
  1038.             OrderedCollection* monitors = kODNULL;
  1039.             ODDispatchModule* module = kODNULL;
  1040.             
  1041.             monitors = _fDispatchTable->GetMonitors(eventType);
  1042.             if (monitors)
  1043.             {
  1044.                 OrderedCollectionIterator iter(monitors);
  1045.                 
  1046.                 for (module = (ODDispatchModule*) iter.First(); 
  1047.                                 iter.IsNotComplete(); 
  1048.                                 module = (ODDispatchModule*) iter.Next())
  1049.                 {
  1050.                     module->Dispatch(ev, eventData, eventInfo);
  1051.                 }
  1052.             }
  1053.             
  1054.             if (!TSMEvent((EventRecord*)eventData))
  1055.             {
  1056.                 module = _fDispatchTable->GetDispatchModule(eventType);
  1057.                 if (module)
  1058.                     handled = module->Dispatch(ev, eventData, eventInfo);
  1059.             }
  1060.         }
  1061.         // Moved to the end so that dispatch modules can monitor or patch
  1062.         // null event handling
  1063.         if ((eventType == nullEvent) && !handled)
  1064.         {
  1065.             somSelf->HandleNullEvent(ev,eventData, kODNULL);
  1066.             handled = kODTrue;
  1067.         }
  1068.             
  1069.     SOM_CATCH_ALL
  1070.     SOM_ENDTRY
  1071.     
  1072.     return handled;
  1073. }
  1074.  
  1075. SOM_Scope void  SOMLINK ODDispatcherExit(ODDispatcher *somSelf, Environment *ev)
  1076. {
  1077.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  1078.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherExit");
  1079.  
  1080.     _fExit = kODTrue;
  1081. }
  1082.  
  1083. SOM_Scope ODBoolean  SOMLINK ODDispatcherShouldExit(ODDispatcher *somSelf, Environment *ev)
  1084. {
  1085.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  1086.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherShouldExit");
  1087.  
  1088.     return _fExit;
  1089. }
  1090.